package com.tfjybj.itoo.exam.provider.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.dmsdbj.itoo.tool.base.service.impl.BaseServicePlusImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tfjybj.itoo.exam.entity.TemplateDetailsEntity;
import com.tfjybj.itoo.exam.model.QuestionTypeClassifyModel;
import com.tfjybj.itoo.exam.model.TemplateDetailsModel;
import com.tfjybj.itoo.exam.provider.dao.QuestionClassifyDao;
import com.tfjybj.itoo.exam.provider.dao.TemplateDetailsDao;
import com.tfjybj.itoo.exam.provider.service.TemplateDetailsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * TemplateDetailsService接口实现类
 * ${base}表
 *
 * @author 任晓帅
 * @version 2.0.0
 * @since 2.0.0 2018-11-15 19:40:28
 */
@Service("templateDetailsService")
public class TemplateDetailsServiceImpl extends BaseServicePlusImpl<TemplateDetailsDao, TemplateDetailsEntity> implements TemplateDetailsService {
	
	//region 模板生成
    @Resource
    private TemplateDetailsDao templateDetailsDao;

    @Resource
    private QuestionClassifyDao questionClassifyDao;

	 @Override
    public PageInfo<TemplateDetailsEntity> queryByLikeTemplateId(String templateId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(templateDetailsDao.queryLikeTemplateId(templateId));
    }

    @Override
    public List<TemplateDetailsModel> selectTempDetails(String templateId) {
        return templateDetailsDao.seltempl(templateId);
    }


    //endregion

    /* **********************************以下为非模板生成的内容********************************* */
    /**
     * 添加 模板详情
     * @author 杨海云
     * @param templateDetailsEntity
     * @return
     */
    @Override
    public int installTemp(TemplateDetailsEntity templateDetailsEntity) {
    return this.templateDetailsDao.insert(templateDetailsEntity);
    }

    /**
     * 根据题型id和课程id查询改课程下包含该类题型的试题分类
     * @param questionTypeId 题型id（单选题，多选题的id）
     * @param courseId 课程id
     * @return 该课程下所有包含该题型的试题分类（所在章节，自定义章节等）
     * @author 杨晓慧
     * @since 2018年12月11日19:07:14
     */
    @Override
    public List<QuestionTypeClassifyModel> getQuestionClassify(String questionTypeId, String courseId , String operator) {
//       1.定义好一个树形结构的modelview
        List<QuestionTypeClassifyModel> treeList=new ArrayList<>();

        //2.查询该课程下所有该题型的所有分类（list，无树形结构）
        List<QuestionTypeClassifyModel> questionTypeClassifyModelList = templateDetailsDao.getQuestionClassify(questionTypeId,courseId,operator);

//        for (QuestionTypeClassifyModel QuestionTypeClassifyModel :questionTypeClassifyModelList) {
//            QuestionTypeClassifyModel.setIsLeaf(true);
//        }
        //3.先把无子节点试题分类（parentId=0的先放进去）
        List<QuestionTypeClassifyModel> listParent = questionTypeClassifyModelList.stream()
                .filter(a -> "0".equals(a.getParentId()))
                .collect(Collectors.toList());
        treeList.addAll(listParent);

        // 4.用stream流把上面获取到的所有parent_id拿过来去重 得到一个父ids数组
        List<String> parentIdList = questionTypeClassifyModelList.stream()
                .map(QuestionTypeClassifyModel::getParentId)
                .collect(Collectors.toList());

        //5.根据父id和当前结构递归调用方法查询试题分类的树形结构
        List<QuestionTypeClassifyModel> treeListChildren= getTreeQuestionClassify(questionTypeClassifyModelList,parentIdList,courseId);

        //6.将查询到的子结构放入父结构
        treeList.addAll(treeListChildren);

        return treeList;
    }

    @Override
    public List<String> getByTemplateId(String id) {
        return templateDetailsDao.getByTemplateId(id);
    }

    /**
     * 随堂小练插入模板明细表
     *
     * @param templateDetailsEntity 模板明细实体
     * @return true/false
     * @author 马莹
     * @since 2019年2月9日19:28:22
     */
    @Override
    public boolean installRandomQuestions(TemplateDetailsEntity templateDetailsEntity) {
        return this.save(templateDetailsEntity);
    }

    /**
     * 根据父id集和和当前树形结构集和返回完整的树形结构（递归此方法）
     * @param questionTypeClassifyModelList 当前嵌套树形结构集和（不完整）
     * @param parentIdList 父id集和
     * @return 完整的树形结构集和
     * @author 杨晓慧
     * @since 2018年12月11日19:07:14
     */
    private List<QuestionTypeClassifyModel>  getTreeQuestionClassify(List<QuestionTypeClassifyModel> questionTypeClassifyModelList , List<String> parentIdList, String courseId){
        //1.定义好一个树形结构的modelview
        List<QuestionTypeClassifyModel> treeList=new ArrayList<>();

        //2.父id數組去重
        HashSet<String> hs=new HashSet<>(parentIdList);
        parentIdList.clear();
        parentIdList.addAll(hs);

        //2.1去除为0或为null的id
        parentIdList.remove(null);
        parentIdList.remove("0");

        //3.循环parentId集和，组织试题分类树形结构
        if (!CollectionUtils.isEmpty(parentIdList)) {
            List<QuestionTypeClassifyModel> questionClassifyTree = templateDetailsDao.getQuestionClassifyTree(parentIdList, courseId);
            parentIdList.forEach(y->{
                // parentIdList中存放的parent_id
                if ( !"0".equals(y)) {
                    //3.1 找到当前parentId下所有子节点
                    List<QuestionTypeClassifyModel> listChildren= questionTypeClassifyModelList.stream()
                            .filter(a -> y.equals(a.getParentId()))
                            .collect(Collectors.toList());
                    //3.2 找到当前父节点的实体信息（使用Optional容器接收避免空指针异常）
                    Optional<QuestionTypeClassifyModel> parent= questionClassifyTree.stream()
                            .filter(a -> y.equals(a.getKey()))
                            .findFirst();
                    //3.3 将children赋值给当前父节点
                    parent.orElse(new QuestionTypeClassifyModel()).setChildren(listChildren);
                    //3.4 在最外层树结构中加入当前父节点
                    treeList.add(parent.orElse(null));
                }
            });

            //4.把上面questionClassifyTree获取到的parent_id拿过来去重 得到一个parent_ids数组
            parentIdList = questionClassifyTree.stream()
                    .map(QuestionTypeClassifyModel::getParentId)
                    .collect(Collectors.toList());

            //4.1 去除为0的父id （为0的父id位于树结构的顶层，到达递归出口，不再参与递归操作）
            parentIdList.remove("0");
            //5.递归该方法,递归出口为所有的parentId都为0（即找到最上层节点）
            return getTreeQuestionClassify(treeList, parentIdList,courseId);
        }else{
            //6.递归出口：当父id集和为空时（）；把递归调用的参数return回去
            return questionTypeClassifyModelList;
        }
    }


}
